<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    function fn () {}  => 创建函数对象, 声明一个函数名变量, 将函数对象的地址值保存到函数名变量中
                          伪代码: var fn = new Function ()
    var a
    console.log(a)
    a = 3
     */

    console.log(a)  // undefined
    var a = 3  // 变量声明提升  => 变量的声明部分被提升到当前作用域的最前面执行  ==> 
                // 预解析 => 在变量声明语句之前就可以访问这个变量, 只是值是undefined

    fn()
    // 函数声明的方式定义函数
    function fn() { // 函数声明提升 => 函数的声明语句提升到当前作用域的最前面执行
                // 预解析  => 在函数声明语句前就可以调用它
      /* 
      var b
      b = 3
       */
      var b = 3
    }
    // 函数表达式的方式定义函数
    var fn2 = function () {
      
    }

    // IIFE  立即调用函数表达式 / 匿名函数自调用
    (function () {
      
    })()

    /* 
    区别语句和表达式
      语句: 
          一个完整的指令, 可以单独存在, 用于做某种数据处理
      表达式:
          不是一个完整的指令, 不能单独存在, 必然会返回某个结果数据

      var a = 3;
      fn();
      var result = fn();
     */

     /* 
     function c() {
       
     }
    //  var c  // 忽略
    console.log(c)
    c = 3
    */
     console.log(c)
     var c = 3
     function c() {
       
     }

     // 立即调用函数表达式  匿名函数自调用  IIFE
    //  (function (){})()
  </script>
</body>
</html>